home *** CD-ROM | disk | FTP | other *** search
- /*
- * KEYMAP child window segment
- * Copyright (c) 1991 by Peter Belew and Bill Hall
- */
-
- #define NOCOMM
- #define NOKANJI
- #define NOATOM
- #define NOSOUND
- #include <windows.h>
- #include <string.h>
- #include "keymap.h"
- #include "winutils.h"
-
- /* local functions */
- static void NEAR KeyWndPaint(HWND hWnd, HDC hDC);
- static int NEAR FindIndex(int sc);
- static void NEAR DoKeyStroke(HWND hWnd, BOOL down);
-
- /* All messages for key windows are processed here */
- long FAR PASCAL KeyWndProc(register HWND hWnd, unsigned message,
- register WORD wParam, LONG lParam)
- {
-
- PAINTSTRUCT ps;
-
- switch(message) {
-
- case WM_LBUTTONDOWN: /* simulate keydown with mouse */
- SetCapture(hWnd);
- DoKeyStroke(hWnd, TRUE);
- break;
-
- case WM_LBUTTONUP: /* simulate keyup with mouse */
- if (hWnd == GetCapture()) {
- DoKeyStroke(hWnd, FALSE);
- ReleaseCapture();
- }
- break;
-
- case WM_CREATE:
- ChildCreate(hWnd); /* initialize kdata structure */
- break;
-
- case WM_PAINT: /* redraw a key window */
- BeginPaint(hWnd, &ps);
- KeyWndPaint(hWnd, ps.hdc);
- EndPaint(hWnd, &ps);
- break;
-
- default:
- return ((long)DefWindowProc(hWnd,message,wParam,lParam));
- break;
- }
- return(0L);
- }
-
- /* simulate a keystroke */
- static void NEAR DoKeyStroke(HWND hWnd, BOOL down)
- {
- WORD sc, vk; /* scan code, virtual key code */
- WORD factor;
- BYTE buf[4];
- BYTE kstate[256];
- int result;
-
- sc = GetWindowWord(hWnd, GWW_ID);
- vk = MapVirtualKey(sc, 1);
- factor = down ? 0 : 0x8000;
-
- if (down) {
- SendMessage(hEdit,WM_KEYDOWN,vk,MAKELONG(1, sc + factor));
- memset(kstate, 0, sizeof(kstate));
- if (GetKeyState(VK_SHIFT) & 0x8000)
- kstate[VK_SHIFT] = 0x80;
- if (GetKeyState(VK_CONTROL) & 0x8000)
- kstate[VK_CONTROL] = 0x80;
- if (GetKeyState(VK_MENU) & 0x8000)
- kstate[VK_MENU] = 0x80;
- if (GetKeyState(VK_CAPITAL) & 1)
- kstate[VK_CAPITAL] = 1;
- result = ToAscii(vk, sc, kstate, buf, 0);
- if (result == 1)
- SendMessage(hEdit,WM_CHAR,buf[0],MAKELONG(1,sc+factor));
- else if (result == 2) {
- SendMessage(hEdit,WM_CHAR,buf[0],MAKELONG(1,sc+factor));
- SendMessage(hEdit,WM_CHAR,buf[2],MAKELONG(1,sc+factor));
- }
- }
- else
- SendMessage(hEdit,WM_KEYUP,vk,MAKELONG(1,sc+factor));
- }
-
- /* fill out the kdata structure for each key */
- void FAR ChildCreate(HWND hWnd)
- {
- WORD vk; /* virtual key code */
- int id; /* key window id */
- int i;
- char kbuf[256]; /* current keyboard state */
- char cbuf[4]; /* character buffer */
- int result;
- WORD spcscan;
-
- spcscan = MapVirtualKey(VK_SPACE,0); /* read space scancode */
- memset(kbuf,0,sizeof(kbuf)); /* all keys up */
- id = GetWindowWord(hWnd, GWW_ID); /* get the window number */
- vk = MapVirtualKey(id, 1); /* find the associated virtual key */
- i = FindIndex(id); /* get the kdata index */
- /* clear the buffers */
- memset(kdata[i].top, 0, sizeof(kdata[i].top));
- memset(kdata[i].bottom, 0, sizeof(kdata[i].bottom));
- kdata[i].caps = 0;
-
- /* clear any pending dead keys */
- ToAscii(VK_SPACE, spcscan, kbuf, cbuf, 0);
-
- result = ToAscii(vk, id, kbuf, cbuf, 0); /* unshifted */
- if (result == 2)
- kdata[i].bottom[0] = cbuf[2]; /* store correct value */
- else if (result == 1)
- kdata[i].bottom[0] = cbuf[0];
- else if (result < 0) {
- kdata[i].bottom[0] = cbuf[0]; /* dead key */
- ToAscii(VK_SPACE,spcscan,kbuf,cbuf,0); /* clear dead key */
- }
-
- kbuf[VK_CAPITAL] = 1; /* repeat the above for lock table */
- result = ToAscii(vk, id, kbuf, cbuf, 0);
- if (result == 2)
- kdata[i].caps = cbuf[2];
- else if (result == 1)
- kdata[i].caps = cbuf[0];
- else if (result < 0) {
- kdata[i].caps = cbuf[0];
- ToAscii(VK_SPACE,spcscan,kbuf,cbuf,0);
- }
- kbuf[VK_CAPITAL] = 0;
-
- kbuf[VK_SHIFT] = 0x80; /* repeat the above with shift key down */
- kbuf[VK_CONTROL] = 0;
- result = ToAscii(vk, id, kbuf, cbuf, 0);
- if (result == 2)
- kdata[i].top[0] = cbuf[2];
- else if (result == 1)
- kdata[i].top[0] = cbuf[0];
- else if (result < 0) {
- kdata[i].top[0] = cbuf[0];
- ToAscii(VK_SPACE, spcscan, kbuf, cbuf, 0);
- }
-
- kbuf[VK_MENU] = 0x80; /* do the same with CTRL-ALT (Alt-gr) */
- kbuf[VK_SHIFT] = 0;
- kbuf[VK_CONTROL] = 0x80;
- result = ToAscii(vk, id, kbuf, cbuf, 0);
- if (result == 2)
- kdata[i].bottom[1] = cbuf[2];
- else if (result == 1)
- kdata[i].bottom[1] = cbuf[0];
- else if (result < 0) {
- kdata[i].bottom[1] = cbuf[0];
- kbuf[VK_MENU] = 0;
- ToAscii(VK_SPACE, spcscan, kbuf, cbuf, 0);
- }
-
- kbuf[VK_MENU] = 0x80; /* finally repeat for Shift CTRL-ALT */
- kbuf[VK_SHIFT] = 0x80;
- kbuf[VK_CONTROL] = 0x80;
- result = ToAscii(vk, id, kbuf, cbuf, 0);
- if (result == 2)
- kdata[i].top[1] = cbuf[2];
- else if (result == 1)
- kdata[i].top[1] = cbuf[0];
- else if (result < 0) {
- kdata[i].top[1] = cbuf[0];
- kbuf[VK_MENU] = 0;
- ToAscii(VK_SPACE, spcscan, kbuf, cbuf, 0);
- }
- /* do some filtering to simplify the display
- but results may depend on language module */
-
- if ('A' <= vk && vk <= 'Z') /* letters, don't show lower case */
- kdata[i].bottom[0] = 0;
- /* also if in caps table and is a letter, don't show lower case */
- else if (IsCharAlpha(kdata[i].caps)
- && (kdata[i].top[0] == kdata[i].caps))
- kdata[i].bottom[0] = 0;
- /* don't repeat duplicates on SHIFT-ALT-gr entries */
- if (AnsiLower(MAKEINTRESOURCE(kdata[i].top[1])) ==
- AnsiLower(MAKEINTRESOURCE(kdata[i].bottom[1]))) {
- kdata[i].bottom[1] = kdata[i].top[1];
- kdata[i].top[1] = 0;
- }
- }
-
- /* draw a key window */
- static void NEAR KeyWndPaint(HWND hWnd, HDC hDC)
- {
-
- RECT rect;
- int i;
- int x,y;
- WORD sc;
-
- sc = GetWindowWord(hWnd, GWW_ID); /* get id of window to draw */
- i = FindIndex(sc);
- GetClientRect(hWnd, &rect);
-
- if (invert) { /* invert the key window */
- SelectObject(hDC, GetStockObject(BLACK_BRUSH));
- SetTextColor(hDC, 0xffffff);
- }
- else
- if (KeyColor == IDM_GRAY) /* draw normally */
- SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
-
- SetBkMode(hDC, TRANSPARENT);
-
- /* draw the outline */
- RoundRect(hDC, rect.left, rect.top, rect.right, rect.bottom,
- rect.right / 8, rect.bottom / 8);
-
- x = 2 * cxborder;
- y = cyborder;
- if (kdata[i].top[0])
- TextOut(hDC, x, y, &kdata[i].top[0], 1);
- if (kdata[i].top[1])
- TextOut(hDC, rect.right / 2, y, &kdata[i].top[1], 1);
- y += cheight + cyborder;
- if (kdata[i].bottom[0])
- TextOut(hDC, x, y, &kdata[i].bottom[0], 1);
- if (kdata[i].bottom[1])
- TextOut(hDC, rect.right / 2, y, &kdata[i].bottom[1], 1);
-
- }
-
- /* find the kdata structure corresponding to a given window index */
- static int NEAR FindIndex(int sc)
- {
- register int i;
-
- for (i = 0; i < MAXKEYS; i++)
- if (sc == kdata[i].scancode)
- break;
-
- return i;
- }
-
- /* subclass the edit window in order to invert the keymap */
- LONG FAR PASCAL LocalEditWndProc(register HWND hWnd,unsigned message,
- register WORD wParam,LONG lParam)
- {
-
- WORD sc;
- HWND hMain;
- HWND hctl;
- BOOL down;
-
- switch(message) {
-
- case WM_KEYDOWN:
- down = TRUE;
- goto keyup;
-
- case WM_KEYUP:
- down = FALSE;
- keyup:
- sc = LOBYTE(HIWORD(lParam)); /* get key window number */
- hMain = GetWindowWord(hWnd, GWW_HWNDPARENT);
- hctl = GetDlgItem(hMain, sc); /* and the handle */
- if (hctl) {
- invert = down ? TRUE : FALSE;
- InvalidateRect(hctl, NULL, TRUE); /* redraw */
- UpdateWindow(hctl);
- } /* return everything to edit wnd proc */
-
- default:
- return(CallWindowProc(fpEditWndProc,hWnd,
- message,wParam,lParam));
- }
- return 0L;
- }
-